<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
		"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
	<title>doh.robot ComboBox/FilteringSelect Test</title>

	<style>
		@import "../../../../util/doh/robot/robot.css";
	</style>

	<!-- required: dojo.js -->
	<script type="text/javascript" src="../../../../dojo/dojo.js"
		djConfig="isDebug: true, parseOnLoad: true"></script>
	<script type="text/javascript">
		dojo.require("dijit.dijit"); // optimize: load dijit layer
		dojo.require("dijit.robotx");

		// TODO: provide URL toggle for FilteringSelect
		var testWidget = "dijit.form.ComboBox";
		var qstr = window.location.search.substr(1);
		if(qstr.length){
		        var qparts = qstr.split("&");
		        for(var x=0; x<qparts.length; x++){
		                var tp = qparts[x].split("=");
		                if(tp[0] == "testWidget"){
		                        testWidget = tp[1];
		                }
		        }
		}
		isComboBox = testWidget=="dijit.form.ComboBox";
		dojo.addOnLoad(function(){

// TODO
// click test for arrowless

			
			doh.robot.initRobot('../_autoComplete.html?testWidget='+testWidget);

			var stateComboBoxes=['setvaluetest', 'datatest', 'combobox4', 'progCombo', 'descending'];
			var countryComboBoxes=['progCombo2', 'progCombo3'];
			var disabledComboBoxes=['combo3'];
			var arrowlessComboBoxes=['arrowless'];
			var dijitComboBoxes=['datatestDijit'];

			var robot_typeValue = function(combo, text, value){
				if(!value || isComboBox) value = text;
				var d = new doh.Deferred();
				doh.robot.mouseMoveAt(combo.focusNode, 500);
				doh.robot.mouseClick({left:true}, 500);
				doh.robot.sequence(function(){ combo.attr('value', null); }, 500);
				doh.robot.typeKeys(text.replace(/^(.).*$/, "$1"), 500);
				doh.robot.typeKeys(text.replace(/^./, ""), 1500, text.length);
				doh.robot.keyPress(dojo.keys.ENTER, 1500+text.length*100);
				doh.robot.sequence(function(){
					if(combo.attr('value') == value && combo.focusNode.value == text && !combo._isShowingNow){
						d.callback(true);
					}else{
						if(combo._isShowingNow){
							// menu could arrive after Enter keypress if it is not thrown out
							combo._hideResultList();
							d.errback(combo.id+" had a menu that did not close after an Enter keypress.");
						}else{
							d.errback(combo.id+" was supposed to have a value of "+value+". Text is "+combo.focusNode.value+", value is "+combo.attr('value'));
						}
					}
				}, 2000);
				return d;
			};

			var findMenuItem = function(combo, text){
				var node = combo._popupWidget.domNode.firstChild;
				while(((node.innerText || node.textContent).indexOf(text)<0) && node.nextSibling){
					node = node.nextSibling;
				}
				return node;
			}

			var robot_selectValue = function(combo, text, value, expectedtext){
				if(!value || isComboBox) value = text;
				if(!expectedtext || isComboBox) expectedtext = text;
				var d = new doh.Deferred();
				doh.robot.mouseMoveAt(combo.downArrowNode, 500);
				doh.robot.mouseClick({left:true}, 500);
				var repeat = function(){
					var node = findMenuItem(combo, text);
					var isMoreChoices = node == combo._popupWidget.nextButton;
					doh.robot.mouseMoveAt(node, 500);
					doh.robot.mouseClick({left:true}, 500);
					if(isMoreChoices){
						// can go faster since the data will have loaded by now
						doh.robot.sequence(repeat, 1000);
					}else{
						doh.robot.sequence(function(){
							if(combo.attr('value') == value && combo.focusNode.value == expectedtext){
								d.callback(true);
							}else{
								d.errback(combo.id+" was supposed to have a value of "+value+". Text is "+combo.focusNode.value+", value is "+combo.attr('value'));
							}
						}, 500);
					}
					
				};
				// first time, wait for the data to come in
				doh.robot.sequence(repeat, 3000);
				return d;
			};
			var robot_a11ySelectValue = function(combo, text, value, expectedtext){
				if(!value || isComboBox) value = text;
				if(!expectedtext || isComboBox) expectedtext = text;
				var d = new doh.Deferred();
				doh.robot.mouseMoveAt(combo.focusNode, 500);
				doh.robot.mouseClick({left:true}, 500);
				doh.robot.sequence(function(){ combo.attr('value', null); }, 500);
				doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
				var repeat = function(){
					var node = findMenuItem(combo, text);
					var isMoreChoices = node == combo._popupWidget.nextButton;
					var selected = combo._popupWidget.getHighlightedOption() || combo._popupWidget.domNode.firstChild;
					while(selected != node){
						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 100);
						selected = selected.nextSibling;
					}
					doh.robot.keyPress(dojo.keys.ENTER, 500);
					if(isMoreChoices){
						// can go faster since the data will have loaded by now
						doh.robot.sequence(repeat, 1000);
					}else{
						doh.robot.sequence(function(){
							if(combo.attr('value') == value && combo.focusNode.value == expectedtext){
								d.callback(true);
							}else{
								d.errback(combo.id+" was supposed to have a value of "+value+". Text is "+combo.focusNode.value+", value is "+combo.attr('value'));
							}
						}, 500);
					}
					
				};
				// first time, wait for the data to come in
				doh.robot.sequence(repeat, 3000);
				return d;
			};

			var errorTest = function(){
				robot_typeValue((this.combo = dijit.byId(this.combo)), "zxcxarax");
				var d = new doh.Deferred();
				doh.robot.sequence(dojo.hitch(this, function(){
					if(isComboBox){
						if(this.combo.isValid() && this.combo.attr('value') == "zxcxarax"){
							d.callback(true);
						}else{
							d.errback(new Error("Good value flagged as bad in ComboBox"));
						}
					}else{
						if(!this.combo.isValid() && this.combo.attr('value') == ""){
							d.callback(true);
						}else{
							if(this.combo.isValid()){
								d.errback(new Error("Bad value permitted in FilteringSelect. Value is: "+this.combo.attr('value')+", text is:"+this.combo.focusNode.value));
							}else{
								d.errback(new Error("Expected value of '', got "+this.combo.attr('value')));
							}
						}
					}
				}), 3000);
				return d;
			};

			// TESTS
			// Verify that all of the form values are correct at init
			doh.register("setUp",
				{
					name:"verifyValues",
					runTest:function(){
						var s;
						if(isComboBox){
							s='state1: California\n'
								+': not fired yet!\n'
								+': not fired yet!\n'
								+'state2: California\n'
								+': not fired yet!\n'
								+'dijitList1: dijit.Editor\n'
								+'state3: California\n'
								+': not fired yet!\n'
								+'state4: \n'
								+': not fired yet!\n'
								+'state5: California\n'
								+'prog: \n'
								+'prog2: \n'
								+'prog3: \n'
								+'descending: California\n'
								+'specialchars: sticks & stones\n'
								+'japanese: \u5357\u5317\n'
								+'labelFunc: Oregon\n';
						}
						else{
							s=': California\n'
								+'state1: CA\n'
								+': not fired yet!\n'
								+': not fired yet!\n'
								+': California\n'
								+'state2: CA\n'
								+': not fired yet!\n'
								+': dijit.Editor\n'
								+'dijitList1: dijit.Editor\n'
								+': California\n'
								+'state3: CA\n'
								+': not fired yet!\n'
								+': \n'
								+'state4: \n'
								+': not fired yet!\n'
								+': California\n'
								+'state5: CA\n'
								+': \n'
								+'prog: \n'
								+': \n'
								+'prog2: \n'
								+': \n'
								+'prog3: \n'
								+': California\n'
								+'descending: CA\n'
								+': sticks & stones\n'
								+'specialchars: sticks\n'
								+': \u5357\u5317\n'
								+'japanese: nanboku\n'
								+': oregon\n'
								+'labelFunc: OR\n';
						}
						doh.is(s, dojo.doc.displayData().replace(/[a-zA-Z0-9_]*_displayed_/g, ""));
					}
				}
			);

			// Press Kentucky
			// This should be a valid assignment
			doh.register("setvaluetest",
				{
					timeout:5000,
					name:"valid",
					combo:"setvaluetest",
					runTest:function(){
						var d = new doh.Deferred();
						this.combo = dijit.byId(this.combo);
						var oc1=dojo.byId('oc1');
						doh.robot.mouseMoveAt('sv1_1', 500);
						doh.robot.mouseClick({left:true}, 500);
						doh.robot.sequence(dojo.hitch(this, function(){
							if(isComboBox){
								if(this.combo.attr('value') == "Kentucky" && oc1.value == "Kentucky"){
									d.callback(true);
								}else{
									d.errback(new Error("Expected Kentucky, got "+this.combo.attr('value')));
								}
							}else{
								if(this.combo.attr('value') == "KY" && this.combo.isValid() && oc1.value == "KY"){
									d.callback(true);
								}else{
									d.errback(new Error("Expected KY, got "+this.combo.attr('value')));
								}
							}
						}), 2000);
						return d;
					}
				}
			);

			// Press Canada
			// This should be an invalid assignment for FilteringSelect, but ok for ComboBox
			doh.register("setvaluetest",
				{
					timeout:5000,
					name:"invalid",
					combo:"setvaluetest",
					runTest:function(){
						var d = new doh.Deferred();
						this.combo = dijit.byId(this.combo);
						var oc1=dojo.byId('oc1');
						doh.robot.mouseMoveAt('sv1_2', 500);
						doh.robot.mouseClick({left:true}, 500);
						doh.robot.sequence(dojo.hitch(this, function(){
							if(isComboBox){
								if(this.combo.attr('value') == "Canada" && oc1.value == "Canada"){
									d.callback(true);
								}else{
									d.errback(new Error("Expected Canada, got "+this.combo.attr('value')));
								}
							}else{
								if(this.combo.attr('value') == "" && !this.combo.isValid() && oc1.value == ""){
									d.callback(true);
								}else{
									d.errback(new Error("Expected Canada, got "+this.combo.attr('value')));
								}
							}
						}), 2000);
						return d;
					}
				}
			);

			// Press null
			// This should be an invalid assignment for FilteringSelect, but ok for ComboBox
			doh.register("setvaluetest",
				{
					timeout:5000,
					name:"nullvalue",
					combo:"setvaluetest",
					runTest:function(){
						var d = new doh.Deferred();
						this.combo = dijit.byId(this.combo);
						var oc1=dojo.byId('oc1');
						doh.robot.mouseMoveAt('sv1_3', 500);
						doh.robot.mouseClick({left:true}, 500);
						doh.robot.sequence(dojo.hitch(this, function(){
							if(isComboBox){
								if(this.combo.attr('value') == "" && oc1.value == ""){
									d.callback(true);
								}else{
									d.errback(new Error("Expected '', got "+this.combo.attr('value')));
								}
							}else{
								if(this.combo.attr('value') == "" && !this.combo.isValid() && oc1.value == ""){
									d.callback(true);
								}else{
									d.errback(new Error("Expected '', got "+this.combo.attr('value')));
								}
							}
						}), 2000);
						return d;
					}
				}
			);

			// Standard tests for all ComboBoxes/FilteringSelects:
			// Type a valid value and press Enter
			// Select a value with the mouse
			// Select a value with the keyboard
			// Type an invalid value and press Enter
			for(var i=0; i<stateComboBoxes.length; i++){
				doh.register("states",
					{
						timeout:60000,
						name:stateComboBoxes[i]+"_type",
						combo:stateComboBoxes[i],
						runTest:function(){
							return robot_typeValue(dijit.byId(this.combo), "California", "CA");
						}
					}
				);

				doh.register("states",
					{
						timeout:60000,
						name:stateComboBoxes[i]+"_select",
						combo:stateComboBoxes[i],
						runTest:function(){
							return robot_selectValue(dijit.byId(this.combo), "Wyoming", "WY");
						}
					}
				);

				doh.register("states",
					{
						timeout:60000,
						name:stateComboBoxes[i]+"_a11y",
						combo:stateComboBoxes[i],
						runTest:function(){
							return robot_a11ySelectValue(dijit.byId(this.combo), "Texas", "TX");
						}
					}
				);

				doh.register("states",
					{
						timeout:60000,
						name:stateComboBoxes[i]+"_error",
						combo:stateComboBoxes[i],
						runTest:function(){
							return (dojo.hitch(this, errorTest))();
						},
						tearDown:function(){
							this.combo.attr("value", isComboBox?"Alaska":"AK");
						}
					}
				);
			}

			for(var i=0; i<countryComboBoxes.length; i++){
				doh.register("countries",
					{
						timeout:60000,
						name:countryComboBoxes[i]+"_type",
						combo:countryComboBoxes[i],
						runTest:function(){
							return robot_typeValue(dijit.byId(this.combo), "Egypt");
						}
					}
				);
				doh.register("countries",
					{
						timeout:60000,
						name:countryComboBoxes[i]+"_select",
						combo:countryComboBoxes[i],
						runTest:function(){
							return robot_selectValue(dijit.byId(this.combo), "Argentina");
						}
					}
				);
				doh.register("countries",
					{
						timeout:60000,
						name:countryComboBoxes[i]+"_a11y",
						combo:countryComboBoxes[i],
						runTest:function(){
							return robot_a11ySelectValue(dijit.byId(this.combo), "Mexico");
						}
					}
				);
				doh.register("countries",
					{
						timeout:60000,
						name:countryComboBoxes[i]+"_error",
						combo:countryComboBoxes[i],
						runTest:function(){
							return (dojo.hitch(this, errorTest))();
						},
						tearDown:function(){
							this.combo.attr("value", "Egypt");
							setTimeout(dojo.hitch(this, function(){
								this.combo.focusNode.blur();
							}), 0);
						}
					}
				);
			}

			// disabled tests+standard tests
			for(var i=0; i<disabledComboBoxes.length; i++){
				doh.register("disabled",
					{
						timeout:1000,
						name:disabledComboBoxes[i]+"_disabledStyle",
						combo:disabledComboBoxes[i],
						runTest:function(){
							this.combo = dijit.byId(this.combo);
							doh.is(true, this.combo.attr('disabled'));
							doh.is(true, this.combo.focusNode.disabled);
						}
					}
				);

				doh.register("disabled",
					{
						timeout:60000,
						name:disabledComboBoxes[i]+"_type",
						combo:disabledComboBoxes[i],
						runTest:function(){
							var d = new doh.Deferred();
							this.combo = dijit.byId(this.combo);
							doh.robot.mouseMoveAt(this.combo.focusNode, 500);
							doh.robot.mouseClick({left:true}, 500);
							doh.robot.typeKeys("Canada", 500);
							// Assert that nothing happened
							doh.robot.sequence(dojo.hitch(this, function(){
								if(this.combo.focusNode.value=="Canada"){
									d.errback(new Error("User was able to type in a disabled ComboBox!"));
								}else{
									d.callback(true);
								}
							}), 2000);
							return d;
						}
					}
				);

				doh.register("disabled",
					{
						timeout:60000,
						name:disabledComboBoxes[i]+"_select",
						combo:disabledComboBoxes[i],
						runTest:function(){
							var d = new doh.Deferred();
							this.combo = dijit.byId(this.combo);
							// Press Arrow Button
							doh.robot.mouseMoveAt(this.combo.downArrowNode, 500);
							doh.robot.mouseClick({left:true}, 500);
							// Assert that nothing happened
							doh.robot.sequence(dojo.hitch(this, function(){
								if(this.combo._popupWidget){
									d.errback(new Error("User was able to open the menu on a disabled ComboBox!"));
								}else{
									d.callback(true);
								}
							}), 2000);
							return d;
						}
					}
				);

				// now enable it and do it again
				doh.register("disabled",
					{
						timeout:30000,
						name:disabledComboBoxes[i]+"_enabledStyle",
						combo:disabledComboBoxes[i],
						runTest:function(){
							var d = new doh.Deferred();
							var button = dojo.byId(this.combo+"_disable");
							this.combo = dijit.byId(this.combo);
							doh.robot.mouseMoveAt(button, 500);
							doh.robot.mouseClick({left:true}, 500);
							doh.robot.sequence(dojo.hitch(this, function(){
								try{
									doh.is(false, this.combo.attr('disabled'));
									doh.is(false, this.combo.focusNode.disabled);
									d.callback(true);
								}catch(e){
									d.errback(new Error("Wrong style after enabling ComboBox."));
								}
							}), 500);
							return d;
						}
					}
				);

				doh.register("disabled",
					{
						timeout:60000,
						name:disabledComboBoxes[i]+"_type",
						combo:disabledComboBoxes[i],
						runTest:function(){
							return robot_typeValue(dijit.byId(this.combo), "California", "CA");
						}
					}
				);

				doh.register("disabled",
					{
						timeout:60000,
						name:disabledComboBoxes[i]+"_select",
						combo:disabledComboBoxes[i],
						runTest:function(){
							return robot_selectValue(dijit.byId(this.combo), "Wyoming", "WY");
						}
					}
				);

				doh.register("disabled",
					{
						timeout:60000,
						name:disabledComboBoxes[i]+"_a11y",
						combo:disabledComboBoxes[i],
						runTest:function(){
							return robot_a11ySelectValue(dijit.byId(this.combo), "Texas", "TX");
						}
					}
				);
				doh.register("disabled",
					{
						timeout:60000,
						name:disabledComboBoxes[i]+"_error",
						combo:disabledComboBoxes[i],
						runTest:function(){
							return (dojo.hitch(this, errorTest))();
						},
						tearDown:function(){
							this.combo.attr("value", isComboBox?"Alaska":"AK");
						}
					}
				);
			}

			for(var i=0; i<dijitComboBoxes.length; i++){
				doh.register("dijits",
					{
						timeout:60000,
						name:dijitComboBoxes[i]+"_type",
						combo:dijitComboBoxes[i],
						runTest:function(){
							return robot_typeValue(dijit.byId(this.combo), "dijit.InlineEditBox");
						}
					}
				);
				doh.register("dijits",
					{
						timeout:60000,
						name:dijitComboBoxes[i]+"_select",
						combo:dijitComboBoxes[i],
						runTest:function(){
							return robot_selectValue(dijit.byId(this.combo), "dijit.layout._LayoutWidget");
						}
					}
				);
				doh.register("dijits",
					{
						timeout:60000,
						name:dijitComboBoxes[i]+"_a11y",
						combo:dijitComboBoxes[i],
						runTest:function(){
							return robot_a11ySelectValue((this.combo = dijit.byId(this.combo)), "dijit.WidgetSet");
						},
						tearDown:function(){
							setTimeout(dojo.hitch(this, function(){
								this.combo.focusNode.blur();
							}), 0);
						}
					}
				);
				doh.register("dijits",
					{
						timeout:60000,
						name:dijitComboBoxes[i]+"_error",
						combo:dijitComboBoxes[i],
						runTest:function(){
							return (dojo.hitch(this, errorTest))();
						},
						tearDown:function(){
							this.combo.attr("value", "dijit.WidgetSet");
						}
					}
				);
			}


			for(var i=0; i<arrowlessComboBoxes.length; i++){
				doh.register("arrowless",
					{
						timeout:60000,
						name:arrowlessComboBoxes[i]+"_type",
						combo:arrowlessComboBoxes[i],
						runTest:function(){
							return robot_typeValue(dijit.byId(this.combo), "California", "CA");
						}
					}
				);
				doh.register("arrowless",
					{
						timeout:60000,
						name:arrowlessComboBoxes[i]+"_a11y",
						combo:arrowlessComboBoxes[i],
						runTest:function(){
							return robot_a11ySelectValue(dijit.byId(this.combo), "Texas", "TX");
						}
					}
				);
				doh.register("arrowless",
					{
						timeout:60000,
						name:arrowlessComboBoxes[i]+"_error",
						combo:arrowlessComboBoxes[i],
						runTest:function(){
							return (dojo.hitch(this, errorTest))();
						},
						tearDown:function(){
							this.combo.attr("value", isComboBox?"Alaska":"AK");
						}
					}
				);
			}

				doh.register("specialchars",
					{
						timeout:60000,
						name:"specialchars_type",
						combo:"specialchars",
						runTest:function(){
							return robot_typeValue(dijit.byId(this.combo), "sticks & stones", "sticks");
						}
					}
				);

				doh.register("specialchars",
					{
						timeout:60000,
						name:"specialchars_a11y",
						combo:"specialchars",
						runTest:function(){
							return robot_a11ySelectValue(dijit.byId(this.combo), "more\\less", "more");
						}
					}
				);

				doh.register("japanese",
					{
						timeout:60000,
						name:"japanese_a11y",
						combo:"japanese",
						runTest:function(){
							return robot_a11ySelectValue((this.combo = dijit.byId(this.combo)), "\u6771\u533A", "higashiku");
						},
						tearDown:function(){
							this.combo.attr("value", isComboBox?"\u6771\u533A":"higashiku");
						}
					}
				);

				doh.register("japanese",
					{
						timeout:60000,
						name:"japanese_type",
						combo:"japanese",
						runTest:function(){
							//return robot_typeValue(, "\u6771\u897F", "touzai");
							var d = new doh.Deferred();
							this.combo = dijit.byId(this.combo);
							doh.robot.mouseMoveAt(this.combo.focusNode);
							doh.robot.mouseClick({left:true}, 500);
							doh.robot.keyPress(dojo.keys.END, 500);
							doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
							doh.robot.keyPress('x', 500, {ctrl:true});
							doh.robot.keyPress(dojo.keys.ENTER, 500);
							doh.robot.sequence(dojo.hitch(this, function(){
								if(this.combo.attr('value') == (isComboBox?"\u6771\u897F":"touzai") && this.combo.focusNode.value=="\u6771\u897F"){
									d.callback(true);
								}else{
									d.errback(this.combo.id+" was supposed to have a value of "+(isComboBox?"\u6771\u897F":"touzai")+". Text is "+this.combo.focusNode.value+", value is "+this.combo.attr('value'));
								}
							}), 500);
							return d;
						}
					}
				);

				doh.register("labelFunc",
					{
						timeout:60000,
						name:"labelFunc_a11y",
						combo:"labelFunc",
						runTest:function(){
							// labelFunc makes Texas texas on FilteringSelect
							return robot_a11ySelectValue((this.combo = dijit.byId(this.combo)), "Texas", isComboBox?null:"TX", isComboBox?null:"texas");
						},
						tearDown:function(){
							this.combo.attr("value", isComboBox?"Texas":"TX");
						}
					}
				);

				doh.register("labelFunc",
					{
						timeout:60000,
						name:"labelFunc_type",
						combo:"labelFunc",
						runTest:function(){
							var d = robot_typeValue((this.combo = dijit.byId(this.combo)), isComboBox?"Alabama":"alabama", "AL");
							return d;
						}
					}
				);

			doh.register("tearDown",
				{
					name:"verifyValues",
					runTest:function(){
						var s;
						if(isComboBox){
							s='state1: Alaska\n'+
							': Alaska\n'+
							': not fired yet!\n'+
							'state2: Alaska\n'+
							': Alaska\n'+
							'dijitList1: dijit.WidgetSet\n'+
							'state3: Alaska\n'+
							': Alaska\n'+
							'state4: Alaska\n'+
							': Alaska\n'+
							'state5: Alaska\n'+
							'prog: Alaska\n'+
							'prog2: Egypt\n'+
							'prog3: Egypt\n'+
							'descending: Alaska\n'+
							'specialchars: more\\less\n'+
							'japanese: \u6771\u897F\n'+
							'labelFunc: Alabama\n';
						}else{
							s=': Alaska\n'+
							'state1: AK\n'+
							': AK\n'+
							': not fired yet!\n'+
							': Alaska\n'+
							'state2: AK\n'+
							': AK\n'+
							': dijit.WidgetSet\n'+
							'dijitList1: dijit.WidgetSet\n'+
							': Alaska\n'+
							'state3: AK\n'+
							': AK\n'+
							': Alaska\n'+
							'state4: AK\n'+
							': AK\n'+
							': Alaska\n'+
							'state5: AK\n'+
							': Alaska\n'+
							'prog: AK\n'+
							': Egypt\n'+
							'prog2: Egypt\n'+
							': Egypt\n'+
							'prog3: Egypt\n'+
							': Alaska\n'+
							'descending: AK\n'+
							': more\\less\n'+
							'specialchars: more\n'+
							': \u6771\u897F\n'+
							'japanese: touzai\n'+
							': alabama\n'+
							'labelFunc: AL\n';
						}
						doh.is(s, dojo.doc.displayData().replace(/[a-zA-Z0-9_]*_displayed_/g, ""));
					}
				}
			);
			doh.run();
		});
	</script>
</head>
</html>
